package com.immomo.test;

import com.immomo.test.common.FileUtil;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.components.ProjectComponent;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.openapi.vfs.newvfs.BulkFileListener;
import com.intellij.openapi.vfs.newvfs.events.VFileEvent;
import com.intellij.util.messages.MessageBusConnection;
import com.tinify.Source;
import com.tinify.Tinify;
import org.jetbrains.annotations.NotNull;

import java.io.File;
import java.util.*;

public class FileChangeDetectApplicationComponent implements ProjectComponent, BulkFileListener {
 
    private final MessageBusConnection connection;
    public static Set<String> compressedPaths = new LinkedHashSet<>();
    public static long compressedTime = 0L;
    private Timer timer;
    private boolean detectChange = false;
    private List<String> pathList = new ArrayList<>();
 
    public FileChangeDetectApplicationComponent() {
        connection = ApplicationManager.getApplication().getMessageBus().connect();
    }
 
    @Override
    public void initComponent() {
        detectChange = FileUtil.loadCanDetectFileChange();
        if (detectChange) {
            connection.subscribe(VirtualFileManager.VFS_CHANGES, this);
        }
    }
 
    @Override
    public void disposeComponent() {
        connection.disconnect();
    }
 
    @Override
    public void before(@NotNull List<? extends VFileEvent> events) {
 
    }
 
    @Override
    public void after(@NotNull List<? extends VFileEvent> events) {
        if (!detectChange) {
            return;
        }
        onFileChangeHandler(events);
    }

    public void onFileChangeHandler(List<? extends VFileEvent> events) {
        for (VFileEvent event : events) {
            pathList.add(event.getPath());
        }
        if (timer == null) {
            timer = new Timer();
            timer.schedule(new TimerTask() {
                @Override
                public void run() {
                    List<String> tmpList = new ArrayList<>(pathList);
                    pathList.clear();
                    showConfirm(tmpList);
                    timer = null;
                }
            }, 1000);
        }
    }

    public void showConfirm(List<String> pathList) {
        for (String s : pathList) {
            if (!s.endsWith("png") && !s.endsWith("jpg")) {
                return;
            }
        }

        Iterator<String> iterator = pathList.iterator();
        while (iterator.hasNext()) {
            String next = iterator.next();
            File file = new File(next);
            if (!file.exists()) {
                iterator.remove();
            }

            if (System.currentTimeMillis() - compressedTime < 1000) {
                if (compressedPaths.contains(next)) {
                    iterator.remove();
                }
            } else {
                compressedPaths.clear();
            }
        }

        if (pathList.isEmpty()) {
            return;
        }

        StringBuilder builder = new StringBuilder();
        for (String s : pathList) {
            builder.append("" + s).append("\n");
        }

        ApplicationManager.getApplication().invokeLater(new Runnable() {
            @Override
            public void run() {
                int message = Messages.showOkCancelDialog("检测到有新增图片\n" +
                        "" + builder.toString() +
                        "是否进行压缩", "提示", Messages.getInformationIcon());
                if (message != 0) {
                    return;
                }
                doCompress(pathList);
            }
        });
    }

    private void doCompress(List<String> pathList) {
        ApplicationManager.getApplication().invokeAndWait(new Runnable() {
            @Override
            public void run() {
                ProgressManager.getInstance().runProcessWithProgressSynchronously(
                        new Runnable() {
                            @Override
                            public void run() {
                                ProgressIndicator progressIndicator = ProgressManager.getInstance().getProgressIndicator();
                                progressIndicator.setIndeterminate(true);
                                String key = FileUtil.loadAPiKey();
                                boolean userCustom = true;
                                if (key == null || "".equals(key.trim())) {
                                    userCustom = false;
                                    key = "xxx";//592333407
                                }
                                StringBuilder builder = new StringBuilder();
                                for (String path : pathList) {
                                    builder.append(doCompressImage(path, key)).append("\n");
                                }
                                builder.append(userCustom ? "自定义API KEY" : "默认API Key");
                                showResultMessage(builder.toString());
                            }
                        }, "正在处理", true, null
                );
            }
        }, ModalityState.NON_MODAL);
    }


    public String doCompressImage(String originPath, String key) {
        StringBuilder info = new StringBuilder();
        Tinify.setKey(key);
        String tempFilePath = originPath + "_tmp";
        File oriFile = new File(originPath);
        File desFile = new File(tempFilePath);
        info.append(oriFile.getName() + ":  ");
        if (!oriFile.exists()) {
            info.append("压缩失败！" + "文件不存在");
            return info.toString();
        }

        try {
            Source source = Tinify.fromFile(originPath);
            source.toFile(tempFilePath);

            float fileSize = FileUtil.getFileSize(oriFile);
            float destFileSize = FileUtil.getFileSize(desFile);
            compressedPaths.add(originPath);
            compressedTime = System.currentTimeMillis();
            FileUtil.renameTo(desFile, oriFile);
            info.append("压缩成功！").append(String.format(" %.2f -> %.2f 压缩比：%.2f %%", fileSize, destFileSize, (fileSize - destFileSize)/fileSize * 100));
        } catch (Exception e) {
            info.append("压缩失败！" + e.getMessage());
        }
        return info.toString();
    }

    private void showResultMessage(String message) {
        ApplicationManager.getApplication().invokeLater(new Runnable() {
            @Override
            public void run() {
                Messages.showMessageDialog(message, "压缩成功", Messages.getInformationIcon());
            }
        });
    }

}